package org.ssc.audience.controller

import au.com.dius.pact.consumer.PactVerificationResult
import au.com.dius.pact.consumer.groovy.PactBuilder
import org.junit.jupiter.api.Tag
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
import org.ssc.audience.AudienceApplication
import org.ssc.audience.feign.TickethouseFeign
import spock.lang.Specification

/**
 * Spock实现Consumer端契约测试示例
 * 验证 tickethouse的/findAudience接口，注入参数到Provider State，用于契约验证的初始化
 */

@SpringBootTest(classes = AudienceApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("test")
class AudienceHandlerContractSpec extends Specification {


    @Autowired
    TickethouseFeign tickethouseFeign;

    def "Contract for find audience by name"() {
        given: "Define DSL"

        //作为参数传给Provider State，告知Provider执行契约测试前先新建Audience
        def providerStateParameters = [
                "aname"   : "aud3",
                "password": "654321",
                "age"     : 30,
                "phone"   : "15661235735",
                "email"   : "aaa@bbb.org"
        ]

        and: "Mock provider"
        def tickethouseService = new PactBuilder()
        tickethouseService {
            serviceConsumer "audience"
            hasPactWith "tickethouse"
            url "localhost"
            port 9000

            //Provider state 'Insert audience'
            given('Insert audience', providerStateParameters)
            uponReceiving("Find a audience")
            withAttributes(
                    method: 'get',
                    path: '/ticket/findAudience/aud3',
            )
            willRespondWith(
                    status: 200,
                    headers: ["Content-Type": "application/json"]
            )
            withBody {
                aid integer(10)
                aname string("foo")
                age integer(30)
                password string("123456")
                phone regexp("1(([38]\\d)|(5[^4&&\\d])|(4[579])|(7[0135678]))\\d{8}", "15661235735")
                email regexp("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*", "aaa@bbb.org")
                state integer(1)
            }

        }

        when: "Verify consumer audience"
        PactVerificationResult result = tickethouseService.runTest {
            def audience = tickethouseFeign.findAudience("aud3")
            assert audience.getAid() == 10
        }

        then: "Check if the result is OK"
        result instanceof PactVerificationResult.Ok
    }

}
